<?php
class PEAR2_Pyrus_Developer_Creator_Phar implements PEAR2_Pyrus_Package_ICreator
{
    /**
     * @var Phar
     */
    protected $phar;
    protected $path;
    protected $stub;
    protected $format;
    protected $compression;
    private $_classname = 'Phar';
    private $_started = false;
    function __construct($path, $stub = false, $fileformat = Phar::TAR, $compression = Phar::GZ)
    {
        if (!class_exists('Phar')) {
            throw new PEAR2_Pyrus_Developer_Creator_Exception(
                'Phar extension is not available');
        }
        if (!Phar::canWrite() || !Phar::isValidPharFilename($path, true)) {
            $this->_classname = 'PharData';
        }
        $this->path = $path;
        $this->stub = $stub;
        $this->compression = $compression;
        $this->format = $fileformat;
    }

    /**
     * save a file inside this package
     * @param string relative path within the package
     * @param string|resource file contents or open file handle
     */
    function addFile($path, $fileOrStream)
    {
        if (!$this->_started) {
            // save package.xml name
            $this->phar->setMetadata($path);
            $this->_started = true;
        }
        $this->phar[$path] = $fileOrStream;
    }

    /**
     * Initialize the package creator
     */
    function init()
    {
        try {
            if (file_exists($this->path)) {
                @unlink($this->path);
            }
            $ext = strstr(strrchr($this->path, '-'), '.');
            if (!$ext) {
                $ext = strstr(strrchr($this->path, '/'), '.');
                if (!$ext) {
                    $ext = strstr(strrchr($this->path, '\\'), '.');
                }
            }
            if (!$ext) {
                $ext = strstr($this->path, '.');
            }
            $a = $this->_classname;
            $this->phar = new $a($this->path);
            if ($this->phar instanceof Phar) {
                $this->phar = $this->phar->convertToExecutable($this->format,
                                                               $this->compression, $ext);
            } else {
                $this->phar = $this->phar->convertToData($this->format,
                                                         $this->compression, $ext);
            }
            $this->phar->startBuffering();
            if ($this->phar instanceof Phar) {
                $this->phar->setStub($this->stub);
            }
            if ($this->format == Phar::ZIP) {
                $this->compression = $comp;
            }
        } catch (Exception $e) {
            throw new PEAR2_Pyrus_Developer_Creator_Exception(
                'Cannot open Phar archive ' . $this->path, $e
            );
        }
        $this->_started = false;
    }

    /**
     * Create an internal directory, creating parent directories as needed
     *
     * This is a no-op for the tar creator
     * @param string $dir
     */
    function mkdir($dir)
    {
        $this->phar->addEmptyDir($dir);
    }

    /**
     * Finish saving the package
     */
    function close()
    {
        if ($this->phar->isFileFormat(Phar::ZIP) && $this->compression !== Phar::NONE) {
            $this->phar->compressFiles($this->compression);
        }
        $this->phar->stopBuffering();
    }
}
